{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":70203,"databundleVersionId":8068726,"sourceType":"competition"}],"dockerImageVersionId":30673,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# BirdCLEF24 🐦‍⬛\n\nThe Goal of this Completations is to identify the Bird Calls in different soundscapes.\n\n\n## Contents :\n\n","metadata":{}},{"cell_type":"markdown","source":"# 📂 Dataset Description\n\n📁 test_soundscapes - The training data consists of short recordings of individual bird calls. These files have been downsampled to 32 kHz where applicable to match the test set audio and converted to the ogg format.\n<br>📁 train_audio - The test_soundscapes directory will be populated with approximately 1,100 audio recordings to be used for scoring. They are 4 minutes long and in ogg audio format. \n<br>📁 unlabeled_soundscapes -  Unlabeled audio data from the same recording locations as the test soundscapes.\n<br>📃 eBird_Taxonomy_v2021.csv - Meta Data Required for Training\n<br>📃 train_metadata.csv - Required MetaData for Model Traning\n<br>📃 sample_submission.csv - Format to Submit a File.\n- `row_id` : A slug of `[soundscape_id]_[end_time]` for the prediction.\n- `[bird_id]` : There are 182 bird ID columns. You will need to predict the probability of the presence of each bird for each row.\n\n\n# 📚 Loading Libraries ","metadata":{}},{"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nimport pickle\n\nimport librosa\n\nimport joblib\nimport tensorflow as tf\nimport tensorflow_io as tfio\n\nfrom tqdm import tqdm\n\nimport matplotlib.pyplot as plt\nimport plotly.graph_objects as go\nimport seaborn as sns\nimport plotly.express as px\n\nimport plotly\n\nfrom IPython.display import display, Audio , display_html\nimport warnings\nwarnings.filterwarnings(\"ignore\")\n\nimport os\nimport multiprocessing\n\nimport gc\ngc.collect()","metadata":{"execution":{"iopub.status.busy":"2024-04-10T11:06:10.396402Z","iopub.execute_input":"2024-04-10T11:06:10.397289Z","iopub.status.idle":"2024-04-10T11:06:15.929422Z","shell.execute_reply.started":"2024-04-10T11:06:10.397252Z","shell.execute_reply":"2024-04-10T11:06:15.928077Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class CFG:\n    train_audio_files = '/kaggle/input/birdclef-2024/train_audio'\n    test_audio_files = '/kaggle/input/birdclef-2024/test_soundscapes'\n    unlabelled_audio_files = '/kaggle/input/birdclef-2024/unlabeled_soundscapes'\n    \n    train_meta_data = '/kaggle/input/birdclef-2024/train_metadata.csv'\n    \n    # Class Names\n    class_names = sorted(os.listdir('/kaggle/input/birdclef-2024/train_audio/'))\n    num_classes = len(class_names)\n    class_labels = list(range(num_classes))\n    label2name = dict(zip(class_labels, class_names))\n    name2label = {v:k for k,v in label2name.items()}\n    \n    \n    # Audio Processing\n    sample_rate = 16000\nconfig=  CFG()\ngc.collect()","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2024-04-10T11:06:15.931578Z","iopub.execute_input":"2024-04-10T11:06:15.932312Z","iopub.status.idle":"2024-04-10T11:06:16.168388Z","shell.execute_reply.started":"2024-04-10T11:06:15.932277Z","shell.execute_reply":"2024-04-10T11:06:16.167348Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 📊 Loading Data\n","metadata":{}},{"cell_type":"code","source":"eBird  = pd.read_csv('/kaggle/input/birdclef-2024/eBird_Taxonomy_v2021.csv')\ntraining_df = pd.read_csv(\"/kaggle/input/birdclef-2024/train_metadata.csv\")\ngc.collect()","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2024-04-10T11:45:31.357670Z","iopub.execute_input":"2024-04-10T11:45:31.358110Z","iopub.status.idle":"2024-04-10T11:45:32.105905Z","shell.execute_reply.started":"2024-04-10T11:45:31.358078Z","shell.execute_reply":"2024-04-10T11:45:32.104520Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Each row shows sicentific name , common_name and abbrivation for that bird, apart from this it also captures the author( The person who captured the recording) with respective location (long/lat). \n\nEach recording dispalys a unique call of the bird it can be `call`,`male`,`adult` or `fight call`.\n\n#### Checking if any null values present in dataset.","metadata":{}},{"cell_type":"code","source":"display(training_df.head(5))\ndisplay(training_df.isna().sum())","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2024-04-10T11:58:10.209532Z","iopub.execute_input":"2024-04-10T11:58:10.209962Z","iopub.status.idle":"2024-04-10T11:58:10.263607Z","shell.execute_reply.started":"2024-04-10T11:58:10.209931Z","shell.execute_reply":"2024-04-10T11:58:10.262109Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"The Features latiture and longitude have `378` null each.<br>\n<b> Evan Features Secondry_Name has null in the form of `[]`, we need to convert them to `na`.\n\n<b> For all the birds, we have respective calls `type`, `filename`.</b><br>\n    \nWe will deal with them later.\n    \n\n### Exploring EBird Data","metadata":{}},{"cell_type":"code","source":"display_html(\"Information \\n\",raw=True)\ndisplay(eBird.info())\ndisplay_html(\"First Few Lines\",raw=True)\ndisplay(eBird.head())\ndisplay_html(\"Displaying Null Values\",raw =True)\ndisplay(eBird.isnull().sum())","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2024-04-10T11:06:16.658737Z","iopub.execute_input":"2024-04-10T11:06:16.659171Z","iopub.status.idle":"2024-04-10T11:06:16.729551Z","shell.execute_reply.started":"2024-04-10T11:06:16.659142Z","shell.execute_reply":"2024-04-10T11:06:16.727534Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"There are total of `16537` entires in data. <br>\nThe features  `SPECIES_GROUP` and `REPORT_AS` are mostly `null`. Feature `FAMILY` and `ORDER1` have null in less numbers.\n\nWe will drop feature `SPECIES_GROUP` and `REPORT_AS`.","metadata":{}},{"cell_type":"code","source":"eBird.drop(['REPORT_AS','SPECIES_GROUP'],axis=1,inplace=True)\ngc.collect()","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2024-04-10T11:06:16.731582Z","iopub.execute_input":"2024-04-10T11:06:16.731974Z","iopub.status.idle":"2024-04-10T11:06:16.965113Z","shell.execute_reply.started":"2024-04-10T11:06:16.731945Z","shell.execute_reply":"2024-04-10T11:06:16.963681Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"training_df.scientific_name.value_counts().reset_index()","metadata":{"execution":{"iopub.status.busy":"2024-04-10T11:06:16.966832Z","iopub.execute_input":"2024-04-10T11:06:16.967282Z","iopub.status.idle":"2024-04-10T11:06:16.988722Z","shell.execute_reply.started":"2024-04-10T11:06:16.967245Z","shell.execute_reply":"2024-04-10T11:06:16.987385Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 📈 Visulaization","metadata":{}},{"cell_type":"code","source":"# px.bar(training_df.common_name.value_counts().reset_index(),y ='common_name',x='count',title='Count of Different Birds in Dataset.')","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2024-04-10T11:06:16.989925Z","iopub.execute_input":"2024-04-10T11:06:16.990465Z","iopub.status.idle":"2024-04-10T11:06:16.999546Z","shell.execute_reply.started":"2024-04-10T11:06:16.990422Z","shell.execute_reply":"2024-04-10T11:06:16.998196Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"px.bar(eBird.FAMILY.value_counts().reset_index(),y='FAMILY',x='count',title = \"Count of Bird's Family\")","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2024-04-10T12:38:53.294846Z","iopub.execute_input":"2024-04-10T12:38:53.295398Z","iopub.status.idle":"2024-04-10T12:38:55.634246Z","shell.execute_reply.started":"2024-04-10T12:38:53.295361Z","shell.execute_reply":"2024-04-10T12:38:55.632845Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<p style = 'font-size:20px'>For visualization of features `longitudes` and `latitudes` we can  drop `nan` values. </p>","metadata":{"execution":{"iopub.status.busy":"2024-04-04T12:56:18.619944Z","iopub.execute_input":"2024-04-04T12:56:18.620429Z","iopub.status.idle":"2024-04-04T12:56:18.649925Z","shell.execute_reply.started":"2024-04-04T12:56:18.620394Z","shell.execute_reply":"2024-04-04T12:56:18.648583Z"}}},{"cell_type":"code","source":"fig = px.scatter_geo(training_df[training_df['longitude'].notnull()],\n                    lat='latitude',\n                    lon='longitude',\n                    title = \"Location of Birds around the World\",\n                    color =\"common_name\",projection='hammer')\n\nfig.show()\n","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2024-04-10T12:39:50.411195Z","iopub.execute_input":"2024-04-10T12:39:50.412301Z","iopub.status.idle":"2024-04-10T12:39:51.201068Z","shell.execute_reply.started":"2024-04-10T12:39:50.412261Z","shell.execute_reply":"2024-04-10T12:39:51.198885Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import plotly.graph_objs as go\n\ndata = [\n    go.Pie(values=eBird.FAMILY.value_counts().reset_index()['count'],\n        labels=eBird.FAMILY.value_counts().reset_index()['FAMILY'],\n        domain={'x':[0.2,0.8], 'y':[0.1,0.9]},\n        hole=0.5,\n        direction='clockwise',\n        sort=False,\n        marker={'colors':['#CB4335','#2E86C1']}\n          ),\n\n    go.Pie(values=eBird.SCI_NAME.value_counts().reset_index()['count'],\n        labels=eBird.SCI_NAME.value_counts().reset_index()['SCI_NAME'],\n        domain={'x':[0.1,0.9], 'y':[0,1]},\n        hole=0.75,\n        direction='clockwise',\n        sort=False,\n        marker={'colors':['#EC7063','#F1948A','#5DADE2','#85C1E9']},\n        showlegend=False\n          )\n]\n\nfig = go.Figure(data=data, layout={'title':'Pie Chart Representing Birds and there respective class.','width':1500,'height':1000})\nfig.update_traces(textinfo='none')\nplotly.offline.iplot(fig)\ngc.collect()","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2024-04-10T12:39:00.145459Z","iopub.execute_input":"2024-04-10T12:39:00.145918Z","iopub.status.idle":"2024-04-10T12:39:01.008246Z","shell.execute_reply.started":"2024-04-10T12:39:00.145882Z","shell.execute_reply":"2024-04-10T12:39:01.006925Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\npx.histogram(training_df,x = 'rating',title = 'Distribution of Rating of Audio Sample')","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2024-04-10T12:39:13.158315Z","iopub.execute_input":"2024-04-10T12:39:13.158765Z","iopub.status.idle":"2024-04-10T12:39:13.239738Z","shell.execute_reply.started":"2024-04-10T12:39:13.158735Z","shell.execute_reply":"2024-04-10T12:39:13.238303Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Visualizing Audio files.","metadata":{}},{"cell_type":"code","source":"audio_path =  training_df.iloc[1]\nx, sr = librosa.load(os.path.join(CFG.train_audio_files,audio_path['filename']),sr = 32000)\ndisplay(Audio(data = os.path.join(CFG.train_audio_files,audio_path['filename'])))\nplt.figure(figsize=(14, 5))\nplt.title(f\"Plotting Audio-Waveform for bird {audio_path['common_name']} for call sign {audio_path['type']} before processing. \")\ndisplay(librosa.display.waveshow(x, sr=sr))\nX = librosa.stft(x)\nXdb = librosa.amplitude_to_db(abs(X))\nplt.figure(figsize=(16, 5))\nplt.title(\"Visual Representations of Spectrum of freqencies before processing.\")\nlibrosa.display.specshow(Xdb, sr=sr, x_axis='time', y_axis='hz') \nplt.colorbar()\nplt.plot()\n\ngc.collect()","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2024-04-10T12:39:17.728586Z","iopub.execute_input":"2024-04-10T12:39:17.728989Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"audio_path =  training_df.iloc[1000]\nx, sr = librosa.load(os.path.join(CFG.train_audio_files,audio_path['filename']),sr = 32000)\ndisplay(Audio(data = os.path.join(CFG.train_audio_files,audio_path['filename'])))\nplt.figure(figsize=(14, 5))\nplt.title(f\"Plotting Audio-Waveform for bird {audio_path['common_name']} for call sign {audio_path['type']} before processing. \")\ndisplay(librosa.display.waveshow(x, sr=sr))\nX = librosa.stft(x)\nXdb = librosa.amplitude_to_db(abs(X))\nplt.figure(figsize=(16, 5))\nplt.title(\"Visual Representations of Spectrum of freqencies before processing.\")\nlibrosa.display.specshow(Xdb, sr=sr, x_axis='time', y_axis='hz') \nplt.colorbar()\nplt.plot()\ngc.collect()","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.idle":"2024-04-10T12:39:49.596883Z","shell.execute_reply.started":"2024-04-10T12:39:24.005922Z","shell.execute_reply":"2024-04-10T12:39:49.595192Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<p style = 'font-size:20px'>Looking at both the signal waves, you can see that , first wave has small difference between the background music and some sound events, where as second sound has higher differece in background noise and sound events.</p>","metadata":{}},{"cell_type":"markdown","source":"# ⚙️ Preprocessing","metadata":{}},{"cell_type":"code","source":"df = training_df.copy(deep=True)\ndrop_columns = []","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2024-04-10T11:57:27.850592Z","iopub.execute_input":"2024-04-10T11:57:27.851063Z","iopub.status.idle":"2024-04-10T11:57:27.859737Z","shell.execute_reply.started":"2024-04-10T11:57:27.851029Z","shell.execute_reply":"2024-04-10T11:57:27.858548Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Finding null in `secondary_labels` and `type` features form dataset","metadata":{}},{"cell_type":"code","source":"df.secondary_labels.value_counts().reset_index()","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2024-04-10T11:57:28.242053Z","iopub.execute_input":"2024-04-10T11:57:28.242583Z","iopub.status.idle":"2024-04-10T11:57:28.262011Z","shell.execute_reply.started":"2024-04-10T11:57:28.242548Z","shell.execute_reply":"2024-04-10T11:57:28.260321Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<p style = 'font-size:20px'>We have total **22567** rows are **null** from `secondary_labels'. </p>","metadata":{}},{"cell_type":"code","source":"def remove_square_braces(text):\n    if text.strip()=='[]' or text.strip()==\"['']\":\n        return np.nan\n    else:\n        return text","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2024-04-10T11:57:28.599735Z","iopub.execute_input":"2024-04-10T11:57:28.600577Z","iopub.status.idle":"2024-04-10T11:57:28.607890Z","shell.execute_reply.started":"2024-04-10T11:57:28.600525Z","shell.execute_reply":"2024-04-10T11:57:28.606903Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df['secondary_labels']=df['secondary_labels'].apply(remove_square_braces)\nprint(\"Total Number of Null entires in SECONDRY_LABELS are :\",df.secondary_labels.isna().sum())\ndrop_columns.append('secondary_labels')","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2024-04-10T11:57:28.810488Z","iopub.execute_input":"2024-04-10T11:57:28.810944Z","iopub.status.idle":"2024-04-10T11:57:28.839006Z","shell.execute_reply.started":"2024-04-10T11:57:28.810893Z","shell.execute_reply":"2024-04-10T11:57:28.837854Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<p style = 'font-size:20px'>The feature <b>secondary_labels</b> will be dropped in training data.","metadata":{}},{"cell_type":"markdown","source":"### Finding empty entires in `type` feature.","metadata":{}},{"cell_type":"code","source":"print(\"Grouping Similar types of calls from birds,\")\ndf.type.value_counts().reset_index()","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2024-04-10T11:57:29.721900Z","iopub.execute_input":"2024-04-10T11:57:29.722563Z","iopub.status.idle":"2024-04-10T11:57:29.742968Z","shell.execute_reply.started":"2024-04-10T11:57:29.722530Z","shell.execute_reply":"2024-04-10T11:57:29.741662Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df['type']=df['type'].apply(remove_square_braces)\nprint(\"Total Number of Null entires in SECONDRY_LABELS are :\",df.type.isna().sum(),\"\\nTotal Null percentage is : \",df.type.isna().sum()/len(df))\ndrop_columns.append(\"type\")","metadata":{"execution":{"iopub.status.busy":"2024-04-10T11:57:32.847236Z","iopub.execute_input":"2024-04-10T11:57:32.847688Z","iopub.status.idle":"2024-04-10T11:57:32.874188Z","shell.execute_reply.started":"2024-04-10T11:57:32.847654Z","shell.execute_reply":"2024-04-10T11:57:32.872676Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<p style = 'font-size:20px'>We will be dropping the type columns as we have 25% of null values.</p>\n\n<p style = 'font-size:20px'>Columns such as  <b>latitude, longitude, scientific_name, common_name, autho, license, rating, url</b> will be dropped as they don't add any value to the model.\n    ","metadata":{}},{"cell_type":"code","source":"df.drop(['secondary_labels', 'type', 'latitude', 'longitude','scientific_name', 'common_name', 'author', 'license', 'rating', 'url'],axis=1,inplace = True)","metadata":{"execution":{"iopub.status.busy":"2024-04-10T12:01:20.869990Z","iopub.execute_input":"2024-04-10T12:01:20.870426Z","iopub.status.idle":"2024-04-10T12:01:20.882748Z","shell.execute_reply.started":"2024-04-10T12:01:20.870396Z","shell.execute_reply":"2024-04-10T12:01:20.881075Z"},"_kg_hide-input":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def load_ogg_file(filename):\n    wave, sr = librosa.load(filename)\n    wave = librosa.resample(wave,orig_sr=sr,target_sr=config.sample_rate)\n    return len(wave)\n\nlengths =joblib.Parallel(n_jobs=8)(joblib.delayed(load_ogg_file)(os.path.join(config.train_audio_files,file)) for file in df['filename'])","metadata":{"execution":{"iopub.status.busy":"2024-04-10T11:06:33.800951Z","iopub.execute_input":"2024-04-10T11:06:33.801378Z","iopub.status.idle":"2024-04-10T11:06:33.807786Z","shell.execute_reply.started":"2024-04-10T11:06:33.801346Z","shell.execute_reply":"2024-04-10T11:06:33.806380Z"},"_kg_hide-input":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(f\"Maximum length of audio within recordings is {max(lengths)}, while minimum lenght of audio is {min(lengths)} with average is {round(max(lengths)/len(lengths),3)}.\\nLongest Audio recording is of {round((max(lengths)/config.sample_rate)/60,3)} mins. \\nSmallest audio recording of length {round(min(lengths)/config.sample_rate,3)} seconds.\")","metadata":{"execution":{"iopub.status.busy":"2024-04-10T12:06:18.407199Z","iopub.execute_input":"2024-04-10T12:06:18.407614Z","iopub.status.idle":"2024-04-10T12:06:18.416990Z","shell.execute_reply.started":"2024-04-10T12:06:18.407585Z","shell.execute_reply":"2024-04-10T12:06:18.415503Z"},"_kg_hide-input":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<p style = 'font-size:20px'>As we need to constraint all the audio recordings at minimal length.<br>We will trim the long audio recordings to certain limit where as adding <b>0</b> to small audio recordings.<br><br>\nFor Training Purpose Trim value to be 180*16000(seconds * sampling rate)</p>\n","metadata":{}},{"cell_type":"code","source":"# In Progress","metadata":{"execution":{"iopub.status.busy":"2024-04-10T12:47:19.375086Z","iopub.execute_input":"2024-04-10T12:47:19.376046Z","iopub.status.idle":"2024-04-10T12:47:19.381223Z","shell.execute_reply.started":"2024-04-10T12:47:19.376000Z","shell.execute_reply":"2024-04-10T12:47:19.380246Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Thank you","metadata":{}},{"cell_type":"code","source":"round()","metadata":{},"execution_count":null,"outputs":[]}]}