{"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":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\n\nnf = 0\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        nf += 1\n#         print(os.path.join(dirname, filename))\n\nprint('Total ', nf, ' files in input data... Starting...')\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Import all the required libraries.\n\nimport numpy as np\nimport pandas as pd\n\nimport librosa\nfrom librosa import display\n\nimport os\nfrom os import path\n\nimport sklearn\nfrom sklearn.model_selection import train_test_split\n\nfrom sklearn.preprocessing import LabelEncoder, StandardScaler\n\n%matplotlib inline\nimport matplotlib.pyplot as plt\n\nimport pathlib\nimport csv \n\n# Import necessary libraries for metrics\nfrom sklearn.metrics import accuracy_score\nfrom sklearn.metrics import precision_score\nfrom sklearn.metrics import recall_score\nfrom sklearn.metrics import f1_score\n\n# Keras\nimport keras\nfrom keras import layers\nfrom keras.models import Sequential\nfrom keras.layers import Activation, Dense, Dropout, Conv2D, Flatten, MaxPooling2D\nfrom keras.layers import GlobalMaxPooling2D, GlobalAveragePooling1D, AveragePooling2D, Input, Add\nfrom tensorflow.keras.optimizers import SGD\n\nfrom datetime import datetime\n\nimport warnings\nwarnings.filterwarnings('ignore')\n\nimport random\n\nprint('Libraries have been imported')\n","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Selecting the 21 species for the competition\n# contained in the file scored_birds.json provided by Kaggle\n\nimport json\n \n# Opening JSON file\nf = open('../input/birdclef-2022/scored_birds.json')\n \n# returns JSON object as a dictionary\nbirds = json.load(f)\n \nprint(birds)\n","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Header for the datafrane containing all features\n\nl = []\n\nfor f in ['chroma_stft', 'chroma_cqt', 'chroma_cens']:\n    for i in range(0,36):\n        l += [f+str(i)]\n\nfor i in range(0,128):\n    l += ['mel_spct'+str(i)]\n\nfor i in range(0,36):\n    l += ['mfcc' + str(i)]\n    \nl += ['spec_cent', 'spec_bw']\n\nfor i in range(0,7):\n    l += ['spec_con' + str(i)]\n\nl += ['spec_flt', 'rolloff_min', 'rolloff_25', 'rolloff_50', 'rolloff_75', 'rolloff_max']\n\nfor i in range(0,6):\n    l += ['tonnetz' + str(i)]\n\nl += ['zcr']\n\nf = l[2:]\nl += ['label']\n\nbirds_fe = pd.DataFrame(columns = l)\n\nfor float_field in f:\n    birds_fe[float_field] = birds_fe[float_field].astype(float, errors = 'raise')\n\nbirds_fe.info()","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Browsing all data directories to extract features\n# Only selected birds will be considered\n# this processs takes some time to complete\n\nnow = datetime.now()\ncurrent_time = now.strftime(\"%H:%M:%S\")\nprint('Feature extraction...\\n')\nprint(\"Begin =\", current_time, \"\\n\")\n\nfor b in birds:   # only selected birds for the competition\n    print('Processing species => ', b)\n    for filename in os.listdir(f'/kaggle/input/birdclef-2022/train_audio/{b}'):\n        # Sound file is loaded\n        soundname = f'/kaggle/input/birdclef-2022/train_audio/{b}/{filename}'\n        y, sr = librosa.load(soundname, mono=True)\n        \n        # Extract features\n        duration = librosa.get_duration(y=y, sr=sr)\n        chroma_stft = librosa.feature.chroma_stft(y=y, sr=sr, n_chroma=36)\n        chroma_cqt = librosa.feature.chroma_cqt(y=y, sr=sr, n_chroma=36)\n        chroma_cens = librosa.feature.chroma_cens(y=y, sr=sr, n_chroma=36)\n        mel_spct = librosa.feature.melspectrogram(y=y, sr=sr)\n        mfcc = librosa.feature.mfcc(y=y, sr=sr, n_mfcc=36)\n        spec_cent = librosa.feature.spectral_centroid(y=y, sr=sr)\n        spec_bw = librosa.feature.spectral_bandwidth(y=y, sr=sr)\n        spec_con = librosa.feature.spectral_contrast(y=y, sr=sr)\n        spec_flt = librosa.feature.spectral_flatness(y=y)\n        rolloff_min = librosa.feature.spectral_rolloff(y=y, sr=sr, roll_percent=0.01)\n        rolloff_25 = librosa.feature.spectral_rolloff(y=y, sr=sr, roll_percent=0.25)\n        rolloff_50 = librosa.feature.spectral_rolloff(y=y, sr=sr, roll_percent=0.50)\n        rolloff_75 = librosa.feature.spectral_rolloff(y=y, sr=sr, roll_percent=0.75)\n        rolloff_max = librosa.feature.spectral_rolloff(y=y, sr=sr, roll_percent=0.99)\n        tonnetz = librosa.feature.tonnetz(y=y, sr=sr)\n        zcr = librosa.feature.zero_crossing_rate(y)\n       \n        new_row = []\n        \n        for k in range(0,36):\n            new_row.append(np.mean(chroma_stft[k,:]))\n        \n        for k in range(0,36):\n            new_row.append(np.mean(chroma_cqt[k,:]))\n         \n        for k in range(0,36):\n            new_row.append(np.mean(chroma_cens[k,:]))\n            \n        for i in range(0,mel_spct.shape[0]):\n            new_row.append(np.mean(mel_spct[i,:]))\n        \n        for e in mfcc:\n            new_row.append(np.mean(e))\n        \n        new_row.append(np.mean(spec_cent))\n        \n        new_row.append(np.mean(spec_bw))\n        \n        for k in range(0,spec_con.shape[0]):\n            new_row.append(np.mean(spec_con[k,:]))\n            \n        new_row.append(np.mean(spec_flt))\n    \n        new_row.append(np.mean(rolloff_min[0]))\n        new_row.append(np.mean(rolloff_25[0]))\n        new_row.append(np.mean(rolloff_50[0]))\n        new_row.append(np.mean(rolloff_75[0]))\n        new_row.append(np.mean(rolloff_max[0]))\n\n        for i in range(0,6):\n            new_row.append(np.mean(tonnetz[i]))\n        \n        new_row.append(np.mean(zcr))\n\n        new_row.append(b)\n        \n        tmp = pd.DataFrame(columns = l)\n        \n        for float_field in f:\n            tmp[float_field] = tmp[float_field].astype(float, errors = 'raise')\n        \n        tmp.loc[len(tmp)] = new_row\n        \n        birds_fe = pd.concat([birds_fe, tmp], ignore_index = True, axis=0)  \n\nnow = datetime.now()\ncurrent_time = now.strftime(\"%H:%M:%S\")\nprint(\"\\nEnd =\", current_time)\n\nprint('\\nFeatures have been extracted')\n","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# just checking\nbirds_fe.head()","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Encoding the Labels\ngenre_list = birds_fe.iloc[:, -1]\nencoder = LabelEncoder()\n\n# Fittng the data\ny = encoder.fit_transform(genre_list)\n\n# Dividing data into training and Testing set\nX = birds_fe.iloc[:, :-1]\nX_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)\n\n# Scaling the Feature columns\nscaler = StandardScaler()\nX_train = scaler.fit_transform(X_train)\nX_test = scaler.transform(X_test)\n\nprint('Labels encoded. Train and Test Datasets, created and standardized.')","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#  Building an ANN model.\n\nmodel = Sequential()\n\nmodel.add(layers.Dense(256, activation='relu', input_shape=(X_train.shape[1],)))\nmodel.add(layers.Dense(128, activation='relu'))\nmodel.add(layers.Dense(64, activation='relu'))\nmodel.add(layers.Dense(32, activation='relu'))\nmodel.add(layers.Dense(21, activation='softmax'))\n\nmodel.compile(optimizer='adam',\n              loss='sparse_categorical_crossentropy',\n              metrics=['accuracy']\n             )\n\nmodel.summary()\n","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Fit the ANN model\n\nprint(\"Fitting the ANN model...\")\n\nnow = datetime.now()\ncurrent_time = now.strftime(\"%H:%M:%S\")\nprint(\"Begin =\", current_time)\n\nclassifier = model.fit(X_train,\n                       y_train,\n                       epochs=50,\n                       validation_data=(X_test, y_test),\n                       batch_size=8,\n                       verbose=0\n                      )\n\nnow = datetime.now()\ncurrent_time = now.strftime(\"%H:%M:%S\")\nprint(\"End =\", current_time)\n\nprint('\\nModel trained')\n","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Part 1:\n\n# Directory where sound files have been placed\ntest_audio_dir = '/kaggle/input/birdclef-2022/test_soundscapes/'\n\n# All sound files will be splitted into 5-second chunks\nchunk_size = 5   \n\n# Getting all the file names from directory\nfile_list = [f.split('.')[0] for f in sorted(os.listdir(test_audio_dir))]\nprint('Number of test soundscapes found:', len(file_list))\n\n# Header for the datafrane containing all features\n\nl = []\n\nfor f in ['chroma_stft', 'chroma_cqt', 'chroma_cens']:\n    for i in range(0,36):\n        l += [f+str(i)]\n\nfor i in range(0,128):\n    l += ['mel_spct'+str(i)]\n\nfor i in range(0,36):\n    l += ['mfcc' + str(i)]\n    \nl += ['spec_cent', 'spec_bw']\n\nfor i in range(0,7):\n    l += ['spec_con' + str(i)]\n\nl += ['spec_flt', 'rolloff_min', 'rolloff_25', 'rolloff_50', 'rolloff_75', 'rolloff_max']\n\nfor i in range(0,6):\n    l += ['tonnetz' + str(i)]\n\nl += ['zcr']\n\n# This is where results are stored before writing the submission file\ndict_pred = {'row_id': [], 'target': []}\n\n# Part 2:\n\n# Traverse all files inside the folder and make chunks of each audio file\nfor afile in file_list: \n    file_path = test_audio_dir + afile + '.ogg'\n    print(f\"Making chunks of size {chunk_size}s of file: {afile}\")\n\n    # Load the file\n    sig, sr = librosa.load(file_path)\n    \n    # Get number of samples for <chunk_size> seconds\n    buffer = chunk_size * sr\n    samples_total = len(sig)\n    samples_wrote = 0\n    \n    counter = 1\n    \n    # each file is chopped up into several chunks.\n    # each chunk is preprocessed and its features extracted to make a prediction\n    while samples_wrote < samples_total:\n        # check if the buffer is not exceeding total samples \n        if buffer > (samples_total - samples_wrote):\n            buffer = samples_total - samples_wrote\n\n        chunk = sig[samples_wrote : (samples_wrote + buffer)]\n        chunk_end_time = counter * 5\n        print(\"Chunk Nº \", counter, \" - Chunk End Time \", chunk_end_time)\n\n        # chunk_features holds all extracted features from the chunk.\n        # this file is fully rewritten for each chunk\n        \n        chunk_features = []\n\n        # Feature extraction from chunk\n        chroma_stft = librosa.feature.chroma_stft(y=chunk, sr=sr, n_chroma=36)\n        chroma_cqt = librosa.feature.chroma_cqt(y=chunk, sr=sr, n_chroma=36)\n        chroma_cens = librosa.feature.chroma_cens(y=chunk, sr=sr, n_chroma=36)\n        mel_spct = librosa.feature.melspectrogram(y=chunk, sr=sr)\n        mfcc = librosa.feature.mfcc(y=chunk, sr=sr, n_mfcc=36)\n        spec_cent = librosa.feature.spectral_centroid(y=chunk, sr=sr)\n        spec_bw = librosa.feature.spectral_bandwidth(y=chunk, sr=sr)\n        spec_con = librosa.feature.spectral_contrast(y=chunk, sr=sr)\n        spec_flt = librosa.feature.spectral_flatness(y=chunk)\n        rolloff_min = librosa.feature.spectral_rolloff(y=chunk, sr=sr, roll_percent=0.01)\n        rolloff_25 = librosa.feature.spectral_rolloff(y=chunk, sr=sr, roll_percent=0.25)\n        rolloff_50 = librosa.feature.spectral_rolloff(y=chunk, sr=sr, roll_percent=0.50)\n        rolloff_75 = librosa.feature.spectral_rolloff(y=chunk, sr=sr, roll_percent=0.75)\n        rolloff_max = librosa.feature.spectral_rolloff(y=chunk, sr=sr, roll_percent=0.99)\n        tonnetz = librosa.feature.tonnetz(y=chunk, sr=sr)\n        zcr = librosa.feature.zero_crossing_rate(chunk)\n        \n        # Extract chunk features\n        for k in range(0,36):\n            chunk_features.append(np.mean(chroma_stft[k,:]))\n        \n        for k in range(0,36):\n            chunk_features.append(np.mean(chroma_cqt[k,:]))\n         \n        for k in range(0,36):\n            chunk_features.append(np.mean(chroma_cens[k,:]))\n            \n        for i in range(0,mel_spct.shape[0]):\n            chunk_features.append(np.mean(mel_spct[i,:]))\n        \n        for e in mfcc:\n            chunk_features.append(np.mean(e))\n        \n        chunk_features.append(np.mean(spec_cent))\n        \n        chunk_features.append(np.mean(spec_bw))\n        \n        for k in range(0,spec_con.shape[0]):\n            chunk_features.append(np.mean(spec_con[k,:]))\n            \n        chunk_features.append(np.mean(spec_flt))\n    \n        chunk_features.append(np.mean(rolloff_min[0]))\n        chunk_features.append(np.mean(rolloff_25[0]))\n        chunk_features.append(np.mean(rolloff_50[0]))\n        chunk_features.append(np.mean(rolloff_75[0]))\n        chunk_features.append(np.mean(rolloff_max[0]))\n\n        for i in range(0,6):\n            chunk_features.append(np.mean(tonnetz[i]))\n        \n        chunk_features.append(np.mean(zcr))   \n\n        # Scaling the features extracted from the chunk\n        chunk_scaled = scaler.transform([chunk_features])\n                \n        # and predicting labels\n        chunk_pred = model.predict(chunk_scaled) # ANN model\n        \n        for bird in birds:\n            i = encoder.transform([bird])\n            row_id = afile + '_' + bird + '_' + str(chunk_end_time)\n            \n            # Put the result into our prediction dict and \n            # apply a \"confidence\" threshold of 0.5\n            dict_pred['row_id'].append(row_id)\n            dict_pred['target'].append(True if chunk_pred[0][i]>0.5 else False)\n\n        # next chunk\n        counter += 1\n        samples_wrote += buffer\n\n# Part 03\n\n# All sound files have been now splitted and the chunks, predicted.\n# With the resulting dictionary make a new data frame and look at some results\n\nresults = pd.DataFrame(dict_pred, columns = ['row_id', 'target'])\n    \n# Convert results to csv\n# results.to_csv(\"/kaggle/working/submission.csv\", index=False)\nresults.to_csv(\"/kaggle/working/submission.csv\", index=False)\n\nprint('Results have been submitted')\n","metadata":{},"execution_count":null,"outputs":[]}]}