{"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**\n\n## **Identify bird calls in soundscapes**\n\n### **I'm working first time in AudioSignal**\n\n### **Version 2: preprocessing in one audio**\n\n#### **--Load --> waveform**\n#### **--fft --> Spectrum**\n#### **--stft --> Spectrogram**\n#### **--MFCCs**\n\n### **Version 5: Generate Json file (Preprocessing)**\n\n### **Version 7: Apply preprocessing output data.json ---> Build CNN model using tensorflow framework**\n\n### ***Now I'm trying Build Model (LSTM) using data.json***\n\n","metadata":{}},{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport librosa,librosa.display\nimport matplotlib.pyplot as plt","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","_kg_hide-input":true,"execution":{"iopub.status.busy":"2022-03-09T14:43:04.968088Z","iopub.execute_input":"2022-03-09T14:43:04.969018Z","iopub.status.idle":"2022-03-09T14:43:07.258254Z","shell.execute_reply.started":"2022-03-09T14:43:04.968896Z","shell.execute_reply":"2022-03-09T14:43:07.257219Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!ls ../input/birdclef-2022","metadata":{"execution":{"iopub.status.busy":"2022-03-09T14:43:07.261025Z","iopub.execute_input":"2022-03-09T14:43:07.261332Z","iopub.status.idle":"2022-03-09T14:43:08.021443Z","shell.execute_reply.started":"2022-03-09T14:43:07.261287Z","shell.execute_reply":"2022-03-09T14:43:08.020307Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **Load**","metadata":{}},{"cell_type":"code","source":"file1 = \"../input/birdclef-2022/train_audio/afrsil1/XC125458.ogg\"","metadata":{"execution":{"iopub.status.busy":"2022-03-09T14:43:08.023905Z","iopub.execute_input":"2022-03-09T14:43:08.024287Z","iopub.status.idle":"2022-03-09T14:43:08.029667Z","shell.execute_reply.started":"2022-03-09T14:43:08.024238Z","shell.execute_reply":"2022-03-09T14:43:08.028198Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **Display_Waveform**","metadata":{}},{"cell_type":"code","source":"import librosa.display\nimport librosa\nsignal,sr = librosa.load(file1,sr = 22050)\nlibrosa.display.waveshow(signal, sr = sr)\nplt.xlabel(\"Time\")\nplt.ylabel(\"Amplitude\")\nplt.show()\n","metadata":{"execution":{"iopub.status.busy":"2022-03-09T14:43:08.033489Z","iopub.execute_input":"2022-03-09T14:43:08.034384Z","iopub.status.idle":"2022-03-09T14:43:09.837281Z","shell.execute_reply.started":"2022-03-09T14:43:08.034337Z","shell.execute_reply":"2022-03-09T14:43:09.836064Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **FFT**\nThe \"Fast Fourier Transform\" (FFT) is an important measurement method in the science of audio and acoustics measurement. It converts a signal into individual spectral components and thereby provides frequency information about the signal.**","metadata":{}},{"cell_type":"code","source":"#fft --> Spectrum\n\nfft = np.fft.fft(signal)\n\nmagnitude = np.abs(fft)\nfrequency = np.linspace(0,sr,len(magnitude))\n\n#plt\nplt.plot(frequency,magnitude)\nplt.xlabel('Frequency')\nplt.ylabel('Magnitude')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-03-09T14:43:09.839126Z","iopub.execute_input":"2022-03-09T14:43:09.839456Z","iopub.status.idle":"2022-03-09T14:43:10.103031Z","shell.execute_reply.started":"2022-03-09T14:43:09.839412Z","shell.execute_reply":"2022-03-09T14:43:10.102112Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## **Left_side_Visualize**","metadata":{}},{"cell_type":"code","source":"#fft --> Spectrum\n\nfft = np.fft.fft(signal)\n\nmagnitude = np.abs(fft)\nfrequency = np.linspace(0,sr,len(magnitude))\n\nleft_frequency = frequency[:int(len(frequency)/2)]\nleft_magnitude = magnitude[:int(len(frequency)/2)]\n\n#plt\nplt.plot(left_frequency,left_magnitude)\nplt.xlabel('Frequency')\nplt.ylabel('Magnitude')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-03-09T14:43:10.106609Z","iopub.execute_input":"2022-03-09T14:43:10.106885Z","iopub.status.idle":"2022-03-09T14:43:10.365297Z","shell.execute_reply.started":"2022-03-09T14:43:10.106857Z","shell.execute_reply":"2022-03-09T14:43:10.3642Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **STFT**\n\nThe Short-time Fourier transform (STFT), is a Fourier-related transform used to determine the sinusoidal frequency and phase content of local sections of a signal as it changes over time.","metadata":{}},{"cell_type":"code","source":"#stft -- spectrogram\n\nn_fft = 2048 #no.of.sample\nhop_length = 512 #amount of shift h-fouriertransform\n\nstft = librosa.core.stft(signal,hop_length=hop_length,n_fft=n_fft)\nspectrogram = np.abs(stft)\n#convert viewable form of low point\nlog_spectrogram = librosa.amplitude_to_db(spectrogram)\n\nlibrosa.display.specshow(log_spectrogram,sr=sr,hop_length=hop_length)\nplt.xlabel(\"Time\")\nplt.ylabel(\"Frequency\")\nplt.colorbar()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-03-09T14:43:10.366985Z","iopub.execute_input":"2022-03-09T14:43:10.367454Z","iopub.status.idle":"2022-03-09T14:43:10.926937Z","shell.execute_reply.started":"2022-03-09T14:43:10.367399Z","shell.execute_reply":"2022-03-09T14:43:10.926101Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **MFCCS**\n\nThe MFCC feature extraction technique basically includes windowing the signal, applying the DFT, taking the log of the magnitude, and then warping the frequencies on a Mel scale, followed by applying the inverse DCT. ","metadata":{}},{"cell_type":"code","source":"#MFCCS\n#n_mfcc013= commonly using\nMFFCS = librosa.feature.mfcc(signal,n_fft=n_fft,hop_length=hop_length,n_mfcc=13)\n\nlibrosa.display.specshow(MFFCS,sr=sr,hop_length=hop_length)\nplt.xlabel(\"Time\")\nplt.ylabel(\"MFFCS\")\nplt.colorbar()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-03-09T14:43:10.928216Z","iopub.execute_input":"2022-03-09T14:43:10.928528Z","iopub.status.idle":"2022-03-09T14:43:11.363951Z","shell.execute_reply.started":"2022-03-09T14:43:10.92849Z","shell.execute_reply":"2022-03-09T14:43:11.363039Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **Apply All data in above preprocessing process**","metadata":{}},{"cell_type":"code","source":"!ls ../input/birdclef-2022","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2022-03-09T14:43:11.366172Z","iopub.execute_input":"2022-03-09T14:43:11.367118Z","iopub.status.idle":"2022-03-09T14:43:12.132597Z","shell.execute_reply.started":"2022-03-09T14:43:11.367072Z","shell.execute_reply":"2022-03-09T14:43:12.131585Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import json\nimport os\n\nPath = \"../input/birdclef-2022/\"\nwith open(os.path.join(Path,\"scored_birds.json\")) as f:\n    scored_birds = json.load(f)\n    \nprint(len(scored_birds))\n\ndf = pd.DataFrame(scored_birds)\ndisplay(df)","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2022-03-09T14:43:12.137388Z","iopub.execute_input":"2022-03-09T14:43:12.137833Z","iopub.status.idle":"2022-03-09T14:43:12.164907Z","shell.execute_reply.started":"2022-03-09T14:43:12.137798Z","shell.execute_reply":"2022-03-09T14:43:12.163668Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"eBird = pd.read_csv(Path +'eBird_Taxonomy_v2021.csv')\ntrain_meta = pd.read_csv(Path +'train_metadata.csv')\ntest = pd.read_csv(Path +'test.csv')","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2022-03-09T14:43:12.166675Z","iopub.execute_input":"2022-03-09T14:43:12.167367Z","iopub.status.idle":"2022-03-09T14:43:12.347429Z","shell.execute_reply.started":"2022-03-09T14:43:12.167321Z","shell.execute_reply":"2022-03-09T14:43:12.346184Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"eBird.sample(3)","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2022-03-09T14:43:12.349564Z","iopub.execute_input":"2022-03-09T14:43:12.350241Z","iopub.status.idle":"2022-03-09T14:43:12.372987Z","shell.execute_reply.started":"2022-03-09T14:43:12.350151Z","shell.execute_reply":"2022-03-09T14:43:12.371816Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_meta.sample(3)","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2022-03-09T14:43:12.375019Z","iopub.execute_input":"2022-03-09T14:43:12.375726Z","iopub.status.idle":"2022-03-09T14:43:12.401092Z","shell.execute_reply.started":"2022-03-09T14:43:12.375665Z","shell.execute_reply":"2022-03-09T14:43:12.400211Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test.sample(3)","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2022-03-09T14:43:12.402769Z","iopub.execute_input":"2022-03-09T14:43:12.403104Z","iopub.status.idle":"2022-03-09T14:43:12.414733Z","shell.execute_reply.started":"2022-03-09T14:43:12.40306Z","shell.execute_reply":"2022-03-09T14:43:12.413638Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!ls ../input/birdclef-2022/train_audio","metadata":{"execution":{"iopub.status.busy":"2022-03-09T14:43:12.417001Z","iopub.execute_input":"2022-03-09T14:43:12.417765Z","iopub.status.idle":"2022-03-09T14:43:13.19955Z","shell.execute_reply.started":"2022-03-09T14:43:12.417718Z","shell.execute_reply":"2022-03-09T14:43:13.198421Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# ***Preprocessing whole data***","metadata":{}},{"cell_type":"code","source":"import os\nimport librosa\nimport math\n\nDATASET_PATH = '../input/birdclef-2022/train_audio'\nJSON_PATH = 'data.json'\nSAMPLE_RATE =  22050\nDURATION = 11\nSAMPLE_PER_TRACK = SAMPLE_RATE * DURATION","metadata":{"execution":{"iopub.status.busy":"2022-03-09T14:43:13.201735Z","iopub.execute_input":"2022-03-09T14:43:13.20211Z","iopub.status.idle":"2022-03-09T14:43:13.209029Z","shell.execute_reply.started":"2022-03-09T14:43:13.202058Z","shell.execute_reply":"2022-03-09T14:43:13.207904Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\ndef save_mfcc(dataset_path,json_path,n_mfcc=13,n_fft=2040,hop_length=512,num_segments=5):\n    \n    #dictionary to store data\n    data = {\n        \"mapping\": [],\n        \"mfcc\": [],\n        \"labels\": []\n    }\n    \n    num_sample_per_segment = int(SAMPLE_PER_TRACK / num_segments)\n    expected_num_mfcc_vectors_per_segment = math.ceil(num_sample_per_segment / hop_length) #1.2 -> 2\n    \n    #Loop through all the birds sound\n    for i,(dirpath,dirnames,filenames) in enumerate(os.walk(dataset_path)):\n        \n        # ensure that were not at the root level\n        \n        if dirpath is not dataset_path:\n            \n            #save the semantic label\n            dirpath_components = dirpath.split(\"/\")\n            semantic_label = dirpath_components[-1]\n            data[\"mapping\"].append(semantic_label)\n            print(\"\\nProcessing {}\".format(semantic_label))\n            \n            #process files for a specific sound\n             \n            for f in filenames:\n                \n                #load audio file\n                file_path = os.path.join(dirpath,f)\n                signal,sr = librosa.load(file_path,sr = SAMPLE_RATE)\n                \n                # process of segments extracting mfcc and storing data \n                for s in range(num_segments):\n                    start_sample = num_sample_per_segment #S=0 -->0\n                    finish_sample = start_sample + num_sample_per_segment #S=0 -> NUM SAMPLES PER SEGMENTS\n                    \n                    mfcc = librosa.feature.mfcc(signal[start_sample:finish_sample],\n                                               sr =sr,\n                                               n_fft=n_fft,\n                                               n_mfcc=n_mfcc,\n                                               hop_length=hop_length)\n                    mfcc = mfcc.T\n                    \n                    #store mfcc for segment if it has the expected length\n                    \n                    if len(mfcc) == expected_num_mfcc_vectors_per_segment:\n                        data[\"mfcc\"].append(mfcc.tolist())\n                        data[\"labels\"].append(i-1)\n                        print(\"{},segment:{}\".format(file_path,s))\n                    \n    with open(json_path,\"w\") as fp:\n        json.dump(data,fp,indent=4)\n\nif __name__ == \"__main__\":\n    save_mfcc(DATASET_PATH,JSON_PATH,num_segments=10)\n    \n\n        ","metadata":{"execution":{"iopub.status.busy":"2022-03-09T14:43:13.211257Z","iopub.execute_input":"2022-03-09T14:43:13.212028Z"},"_kg_hide-output":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **Build the model ---> LSTM-Tensorflow**","metadata":{}},{"cell_type":"code","source":"import json\nimport numpy as np\nfrom sklearn.model_selection import train_test_split\nimport tensorflow.keras as keras\nimport matplotlib.pyplot as plt\n\nDATA_PATH = \"./data.json\"\n\n\ndef load_data(data_path):\n    \"\"\"Loads training dataset from json file.\n        :param data_path (str): Path to json file containing data\n        :return X (ndarray): Inputs\n        :return y (ndarray): Targets\n    \"\"\"\n\n    with open(data_path, \"r\") as fp:\n        data = json.load(fp)\n\n    X = np.array(data[\"mfcc\"])\n    y = np.array(data[\"labels\"])\n    return X, y\n\n\ndef plot_history(history):\n    \"\"\"Plots accuracy/loss for training/validation set as a function of the epochs\n        :param history: Training history of model\n        :return:\n    \"\"\"\n\n    fig, axs = plt.subplots(2)\n\n    # create accuracy sublpot\n    axs[0].plot(history.history[\"accuracy\"], label=\"train accuracy\")\n    axs[0].plot(history.history[\"val_accuracy\"], label=\"test accuracy\")\n    axs[0].set_ylabel(\"Accuracy\")\n    axs[0].legend(loc=\"lower right\")\n    axs[0].set_title(\"Accuracy eval\")\n\n    # create error sublpot\n    axs[1].plot(history.history[\"loss\"], label=\"train error\")\n    axs[1].plot(history.history[\"val_loss\"], label=\"test error\")\n    axs[1].set_ylabel(\"Error\")\n    axs[1].set_xlabel(\"Epoch\")\n    axs[1].legend(loc=\"upper right\")\n    axs[1].set_title(\"Error eval\")\n\n    plt.show()\n\n\ndef prepare_datasets(test_size, validation_size):\n    \"\"\"Loads data and splits it into train, validation and test sets.\n    :param test_size (float): Value in [0, 1] indicating percentage of data set to allocate to test split\n    :param validation_size (float): Value in [0, 1] indicating percentage of train set to allocate to validation split\n    :return X_train (ndarray): Input training set\n    :return X_validation (ndarray): Input validation set\n    :return X_test (ndarray): Input test set\n    :return y_train (ndarray): Target training set\n    :return y_validation (ndarray): Target validation set\n    :return y_test (ndarray): Target test set\n    \"\"\"\n\n    # load data\n    X, y = load_data(DATA_PATH)\n\n    # create train, validation and test split\n    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=test_size)\n    X_train, X_validation, y_train, y_validation = train_test_split(X_train, y_train, test_size=validation_size)\n\n    return X_train, X_validation, X_test, y_train, y_validation, y_test\n\n\ndef build_model(input_shape):\n    \"\"\"Generates RNN-LSTM model\n    :param input_shape (tuple): Shape of input set\n    :return model: RNN-LSTM model\n    \"\"\"\n\n    # build network topology\n    model = keras.Sequential()\n\n    # 2 LSTM layers\n    model.add(keras.layers.LSTM(64, input_shape=input_shape, return_sequences=True))\n    model.add(keras.layers.LSTM(64))\n\n    # dense layer\n    model.add(keras.layers.Dense(64, activation='relu'))\n    model.add(keras.layers.Dropout(0.3))\n\n    # output layer\n    model.add(keras.layers.Dense(152, activation='softmax'))\n\n    return model\n\n\nif __name__ == \"__main__\":\n\n    # get train, validation, test splits\n    X_train, X_validation, X_test, y_train, y_validation, y_test = prepare_datasets(0.25, 0.2)\n\n    # create network\n    input_shape = (X_train.shape[1], X_train.shape[2]) # 130, 13\n    model = build_model(input_shape)\n\n    # compile model\n    optimiser = keras.optimizers.Adam(learning_rate=0.0001)\n    model.compile(optimizer=optimiser,\n                  loss='sparse_categorical_crossentropy',\n                  metrics=['accuracy'])\n\n    model.summary()\n\n    # train model\n    history = model.fit(X_train, y_train, validation_data=(X_validation, y_validation), batch_size=32, epochs=30)\n\n    # plot accuracy/error for training and validation\n    plot_history(history)\n\n    # evaluate model on test set\n    test_loss, test_acc = model.evaluate(X_test, y_test, verbose=2)\n    print('\\nTest accuracy:', test_acc)","metadata":{"_kg_hide-input":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#save model\nmodel.save('fg_model.h5')","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## **Update_Next_ComingSoon.........**\n\n**Reference: [https://youtu.be/szyGiObZymo](http://)**","metadata":{}}]}